export class JsonUtil {
  /**
   * 安全解析JSON字符串
   * @param jsonString JSON字符串
   * @param defaultValue 解析失败时的默认值
   * @returns 解析结果或默认值
   */
  public static parse<T>(jsonString: string, defaultValue: T): T {
    try {
      return JSON.parse(jsonString) as T;
    } catch (error) {
      return defaultValue;
    }
  }

  /**
   * 安全stringify JSON对象
   * @param value 要转换的值
   * @param space 缩进空格数，默认为2
   * @returns JSON字符串，失败时返回空字符串
   */
  public static stringify(value: any, space: number = 2): string {
    try {
      return JSON.stringify(value, null, space);
    } catch (error) {
      return '';
    }
  }

  /**
   * 从对象中获取嵌套属性值
   * @param obj 源对象
   * @param path 属性路径，例如 "user.profile.name"
   * @param defaultValue 未找到时的默认值
   * @returns 属性值或默认值
   */
  public static getNestedValue<T>(obj: any, path: string, defaultValue: T): T {
    const keys = path.split('.');
    let current = obj;
    
    for (const key of keys) {
      if (current === null || current === undefined || typeof current !== 'object') {
        return defaultValue;
      }
      current = current[key];
    }
    
    return (current === undefined) ? defaultValue : current as T;
  }

  /**
   * 合并多个对象
   * @param objects 要合并的对象数组
   * @returns 合并后的新对象
   */
  public static merge(...objects: Record<string, any>[]): Record<string, any> {
    return objects.reduce((result, current) => {
      return { ...result, ...current };
    }, {});
  }

  /**
   * 深度复制对象
   * @param obj 要复制的对象
   * @returns 复制后的新对象
   */
  public static deepClone<T>(obj: T): T {
    if (obj === null || typeof obj !== 'object') {
      return obj;
    }
    
    try {
      return JSON.parse(JSON.stringify(obj));
    } catch (error) {
      return obj;
    }
  }

  /**
   * 从对象中移除指定的属性
   * @param obj 源对象
   * @param keys 要移除的属性名数组
   * @returns 移除属性后的新对象
   */
  public static omit<T extends Record<string, any>, K extends keyof T>(
    obj: T,
    keys: K[]
  ): Omit<T, K> {
    const result = { ...obj };
    keys.forEach(key => {
      delete result[key];
    });
    return result;
  }

  /**
   * 从对象中选择指定的属性
   * @param obj 源对象
   * @param keys 要选择的属性名数组
   * @returns 只包含选择属性的新对象
   */
  public static pick<T extends Record<string, any>, K extends keyof T>(
    obj: T,
    keys: K[]
  ): Pick<T, K> {
    const result = {} as Pick<T, K>;
    keys.forEach(key => {
      if (key in obj) {
        result[key] = obj[key];
      }
    });
    return result;
  }
}
